package com.ccrfid.rmc6.service.business.prison.door;

import com.ccrfid.rmc6.entity.business.prison.door.InOutDoorEntity;
import com.ccrfid.rmc6.lbservice3.pojo.locate.PersonnelLocateInfo;
import com.ccrfid.rmc6.lbservice3.pojo.msg.MsgLocate;
import com.ccrfid.rmc6.pojo.Constants;
import com.ccrfid.rmc6.pojo.dto.prison.door.InOutDoorMsg;
import com.ccrfid.rmc6.util.JsonUtil;
import com.ccrfid.rmc6.util.SleepUtil;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.sql.Timestamp;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
public class InOutDoorManager {
    private static final Logger logger = LoggerFactory.getLogger(InOutDoorManager.class);
    private List<InOutDoorEntity> doorList = new CopyOnWriteArrayList();
    private Set<Integer> locatorSet = new CopyOnWriteArraySet<>();

    @Autowired
    private EventBus eventBus;
    @Autowired
    private DoorService doorService;

    @PostConstruct
    private void init() {
        initData();
        eventBus.register(this);
    }

    @Subscribe
    public void onPersonnelLocateInfo(PersonnelLocateInfo locateInfo) {
        if (locateInfo.getPersonnelType() != null
                && locateInfo.getPersonnelType().equals(Constants.PERSONNEL_TYPE.PRISONER.id)) {
            MsgLocate msgLocate = locateInfo.getMsgLocate();
            if (locatorSet.contains(msgLocate.getCurrentLocator()) && locatorSet.contains(msgLocate.getFrontLocator())) {
                //进入, in
                doorList.parallelStream()
                        .filter(door -> msgLocate.getFrontLocator().equals(door.getOutLocatorAddress())
                                && msgLocate.getCurrentLocator().equals(door.getInLocatorAddress()))
                        .forEach(door -> {
                            InOutDoorMsg inOutDoorMsg = new InOutDoorMsg(door.getId(), "in", locateInfo.getPersonnelId(),
                                    locateInfo.getPersonnelName(), msgLocate.getCardNumber(), new Timestamp(msgLocate.getTime()));
                            eventBus.post(inOutDoorMsg);
                        });
                //离开, out
                doorList.parallelStream()
                        .filter(door -> msgLocate.getFrontLocator().equals(door.getInLocatorAddress())
                                && msgLocate.getCurrentLocator().equals(door.getOutLocatorAddress()))
                        .forEach(door -> {
                            InOutDoorMsg inOutDoorMsg = new InOutDoorMsg(door.getId(), "out", locateInfo.getPersonnelId(),
                                    locateInfo.getPersonnelName(), msgLocate.getCardNumber(), new Timestamp(msgLocate.getTime()));
                            eventBus.post(inOutDoorMsg);
                        });
            }
        }
    }

    private void initData() {
        List<InOutDoorEntity> list = doorService.getAllDoors();
        if (list != null && list.size() > 0) {
            for (InOutDoorEntity doorEntity : list) {
                doorList.add(doorEntity);
                locatorSet.add(doorEntity.getInLocatorAddress());
                locatorSet.add(doorEntity.getOutLocatorAddress());
            }
        }
    }

    @JmsListener(destination = "ws_door_add", containerFactory = "topicListenerCF")
    public void onDoorAdd(String content) {
        SleepUtil.sleepSeconds(1);
        InOutDoorEntity doorEntity = JsonUtil.INSTANCE.readValue(content, InOutDoorEntity.class);
        doorList.add(doorEntity);
        locatorSet.add(doorEntity.getInLocatorAddress());
        locatorSet.add(doorEntity.getOutLocatorAddress());
    }

    @JmsListener(destination = "ws_door_update", containerFactory = "topicListenerCF")
    public void onDoorUpdate(String content) {
        SleepUtil.sleepSeconds(1);
        InOutDoorEntity doorEntity = JsonUtil.INSTANCE.readValue(content, InOutDoorEntity.class);
        for (InOutDoorEntity entity : doorList) {
            if (entity.getId().equals(doorEntity.getId())) {
                locatorSet.remove(entity.getInLocatorAddress());
                locatorSet.remove(entity.getOutLocatorAddress());
                locatorSet.add(doorEntity.getInLocatorAddress());
                locatorSet.add(doorEntity.getOutLocatorAddress());

                entity.setInLocatorAddress(doorEntity.getInLocatorAddress());
                entity.setOutLocatorAddress(doorEntity.getOutLocatorAddress());
                entity.setRemark(doorEntity.getRemark());
            }
        }
    }

    @JmsListener(destination = "ws_door_delete", containerFactory = "topicListenerCF")
    public void onDoorDelete(String content) {
        SleepUtil.sleepSeconds(1);
        Long doorId = JsonUtil.INSTANCE.readValue(content, Long.class);
        for (InOutDoorEntity entity : doorList) {
            if (entity.getId().equals(doorId)) {
                locatorSet.remove(entity.getInLocatorAddress());
                locatorSet.remove(entity.getOutLocatorAddress());
                doorList.remove(entity);
            }
        }
    }
}
